/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [Example_12_Overriding.java]
 * Creation Date        [24-Jun-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_02_oop;

/**
 * 方法重写测试
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class Example_12_Overriding {

	/**
	 * 测试方法
	 * 
	 * @param args
	 *            命令行参数
	 */
	@SuppressWarnings("static-access")
	public static void main(String[] args) {

		// 继承时属性的隐藏问题
		DerivedClass child = new DerivedClass();
		System.out.println("Child name is " + child.name + ", Child age is "
				+ child.age + " ,Kind is " + child.kind);// 此处得到都是Child类的变量值

		// 将Child类型转换为Parent类型, 即多态情况
		BaseClass parent = new DerivedClass(); // BaseClass parent = child;
		System.out.println("转换为Parent之后的name is " + parent.name + ", age is "
				+ parent.age + " ,kind is " + parent.kind);
		/*
		 * 结论:
		 * 
		 * 父类的实例变量和类变量能被子类的同名变量遮盖(隐藏), 将子类对象转换为父类对象后, 可以访问父类对象的实例变量和类变量
		 * 
		 * 在子类中如果需要访问父类中被隐藏的实例变量, 需要使用"super.属性名"
		 * 
		 * 在子类中如果需要访问父类中被隐藏的类变量, 需要使用"父类名.属性名"
		 */
		System.out.println("子类访问父类被隐藏的实例变量: " + child.getParentName());
		System.out.println("子类访问父类被隐藏的类变量: " + child.getParentKind());

		// 继承时方法的覆盖与隐藏问题
		child.getName();
		child.getKind();
		parent.getName();
		parent.getKind();
		/*
		 * 结论:
		 * 
		 * 父类的静态方法被子类的同名静态方法隐藏, 而父类的实例方法被子类的实例方法覆盖(重写)
		 * 
		 * 将子类转换为父类对象后(或者多态), 能访问父类的静态方法,不能访问父类的实例方法(调用的方法为被子类重写后的方法)
		 */
	}

}

/**
 * 父类
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 */
class BaseClass {

	/**
	 * 类变量, Parent的类别
	 */
	public static String kind = "pkg_02_oop.Example_12_Overriding.BaseClass";
	/**
	 * 类变量, Parent的年龄
	 */
	public static int age = 50;
	/**
	 * 实例变量, Parent的名称
	 */
	public String name = "Parent";

	/**
	 * 静态方法, 获得Parent的类别
	 * 
	 * @return 类别的字符串表示
	 */
	public static String getKind() {
		System.out.println("Parent getKind() method called");
		return kind;
	}

	/**
	 * 静态方法, 获得Parent的年龄
	 * 
	 * @return 年龄的数字表示
	 */
	public static int getAge() {
		System.out.println("Parent getAge() method called");
		return age;
	}

	/**
	 * 实例方法, 获得Parent的名称
	 * 
	 * @return 父类的名称
	 */
	public String getName() {
		System.out.println("Parent getName() method called");
		return name;
	}
}

/**
 * 子类
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 */
class DerivedClass extends BaseClass {

	/**
	 * 类变量, Child的类别
	 */
	public static String kind = "pkg_02_oop.Example_12_Overriding.DerivedClass";
	/**
	 * 类变量, Child的年龄
	 */
	public static int age = 25;
	/**
	 * 实例变量, Child的名称
	 */
	public String name = "child";

	/**
	 * 静态方法, 获得Child的类别
	 * 
	 * @return 子类的类别
	 */
	public static String getKind() {
		System.out.println("Child getKind() method called");
		return kind;
	}

	/**
	 * 静态方法, 获得Child的年龄
	 * 
	 * @return 子类的年龄
	 */
	public static int getAge() {
		System.out.println("Child getAge() method called");
		return age;
	}

	/**
	 * 实例方法, 获得Child的名称
	 * 
	 * @return 子类的名称
	 */
	@Override
	public String getName() {
		System.out.println("Child getName() method called");
		return name;
	}

	/**
	 * 实例方法, 获得Parent的名称
	 * 
	 * @return 父类的名称
	 */
	public String getParentName() {
		return super.name;
	}

	/**
	 * 静态方法, 获得Parent的类别
	 * 
	 * @return 父类的类别
	 */
	public static String getParentKind() {
		return BaseClass.kind;
	}
}
